Site picker
Allow users to select a site.
#Examples
Default: Button shows selected site or an empty placeholder text if no site is selected.
The site picker consists of two main elements:
- Button (with icon) to display the selected site.
 - Popover (triggered by button click) with a table of sites and default columns with data related to the site.
 
type SitesRequest = { query: string; page: number; pageSize: number; sortField: SortField<Site> };
const [request, setRequest] = useState<SitesRequest>({
	query: "",
	page: 1,
	pageSize: 20,
	sortField: { property: "isFavorite", direction: "asc" },
});
const { api } = useDataAPI();
const fetchDataFn = async (request: SitesRequest, signal?: AbortSignal) =>
	await api.getSites(request, signal);
const { data, loading, triggerRender } = useData(fetchDataFn, request);
const [selected, setSelected] = useState<Site>();
return (
	<PageHeaderPickers
		items={
			data && (
				<SitePicker
					items={data.items}
					sort={request.sortField}
					setSort={(property, direction) =>
						setRequest({
							...request,
							sortField: {
								property,
								direction:
									property === request.sortField.property
										? invertDirection(request.sortField.direction)
										: direction,
							},
						})
					}
					search={{
						query: request.query,
						onSearch: (query) => setRequest({ ...request, query }),
					}}
					onLoadMore={() => setRequest((prev) => ({ ...prev, pageSize: prev.pageSize + 20 }))}
					totalItems={data.totalItems}
					selectedSite={selected}
					onSelectedSite={setSelected}
					onFavorite={async (site, isFavorite) => {
						await api.updateFavoriteSite(site, isFavorite);
						triggerRender();
					}}
					editSitesUrl="https://fancy.siteimprove.com/"
					loading={loading}
				/>
			)
		}
	/>
);
#Usage with no sites
Used when data is unavailable.
return (
	<PageHeaderPickers
		items={
			<SitePicker
				items={[]}
				sort={{ property: "isFavorite", direction: "asc" }}
				setSort={() => {}}
				search={{
					query: "",
					onSearch: () => {},
				}}
				onLoadMore={() => {}}
				onSelectedSite={() => {}}
				onFavorite={() => {}}
				totalItems={0}
				editSitesUrl="https://fancy.siteimprove.com/"
			/>
		}
	/>
);#Usage with many sites
The load more button will load more sites.
type SitesRequest = { query: string; page: number; pageSize: number; sortField: SortField<Site> };
const take = 20;
const [request, setRequest] = useState<SitesRequest>({
	query: "",
	page: 1,
	pageSize: take,
	sortField: { property: "isFavorite", direction: "asc" },
});
const { api } = useDataAPI();
const fetchDataFn = async (request: SitesRequest, signal?: AbortSignal) => {
	await new Promise((resolve) => setTimeout(resolve, 2000));
	return await api.getSitesLarge(request, signal);
};
const { data, loading, triggerRender } = useData(fetchDataFn, request);
const [selected, setSelected] = useState<Site>();
const pickersLoading = loading && data === null;
return (
	<PageHeaderPickers
		loading={pickersLoading}
		items={
			data && (
				<SitePicker
					items={data.items}
					loading={loading}
					sort={request.sortField}
					setSort={(property, direction) =>
						setRequest((prev) => ({
							...prev,
							sortField: {
								property,
								direction:
									property === request.sortField.property
										? invertDirection(request.sortField.direction)
										: direction,
							},
						}))
					}
					search={{
						query: request.query,
						onSearch: (query) => setRequest({ ...request, query }),
					}}
					onLoadMore={() => setRequest((prev) => ({ ...prev, pageSize: prev.pageSize + take }))}
					totalItems={data.totalItems}
					selectedSite={selected}
					onSelectedSite={setSelected}
					onFavorite={async (site, isFavorite) => {
						await api.updateFavoriteSiteLarge(site, isFavorite);
						triggerRender();
					}}
					editSitesUrl="https://fancy.siteimprove.com/"
					extraColumns={[colPages(), colVisits()]}
				/>
			)
		}
	/>
);
#Properties
| Property | Description | Defined | Value | 
|---|---|---|---|
itemsRequired  | object[]Items displayed in the site picker. | ||
totalItemsRequired  | numberTotal amount of sites. | ||
sortRequired  | objectProperty and direction by which the sites table is sorted. | ||
setSortRequired  | functionCallback for updating sorting. | ||
searchRequired  | objectSearch options to filter sites. | ||
onLoadMoreRequired  | functionLoad more items callback | ||
onFavoriteRequired  | functionCallback to favorite/unfavorite a site | ||
onSelectedSiteRequired  | functionCallback when a site is selected | ||
selectedSiteOptional  | objectSelected site item | ||
loadingOptional  | booleanIf the site picker is loading | ||
extraColumnsOptional  | type-union[]Extra columns to be displayed in the site picker additional to the default columns | ||
editSitesUrlOptional  | stringURL to edit sites page | ||
textsOptional  | objectTexts for the site picker | 
#Guidelines
#Do's
#Don'ts
#Accessibility
Explore detailed guidelines for this component: Accessibility Specifications